home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PRINTER / HPMAZE02.ARJ / HP3DMAZE.C < prev    next >
Text File  |  1991-04-24  |  49KB  |  1,261 lines

  1. /*
  2.          This program will generate a three dimensional maze suitable for
  3.     printing on a Hewlett-Packard LaserJet II printer.  A different random
  4.     number seed will produce a different maze.
  5.  
  6.          Written by James L. Dean
  7.                     406 40th Street
  8.                     New Orleans, LA 70124
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <malloc.h>
  14.  
  15. #define TRUE 1
  16. #define FALSE 0
  17.  
  18. #define EBCDIC 0
  19.  
  20. /* printer constants */
  21. #define DOTS_PER_INCH      150
  22. #define WIDTH_IN_INCHES    8.5
  23. #define LENGTH_IN_INCHES   11.0
  24. #define DOTS_PER_STROKE    2    /* 300/DOTS_PER_INCH */
  25. #define NUM_X_BYTES        206  /* (int) (LENGTH_IN_INCHES*DOTS_PER_INCH/8) */
  26. #define X_BYTE_MAX         205  /* NUM_X_BYTES-1 */
  27. #define NUM_X_DOTS         1648 /* 8*NUM_X_BYTES */
  28. #define X_DOT_MAX          1647 /* NUM_X_DOTS-1 */
  29. #define NUM_Y_DOTS         1275 /* (int) (WIDTH_IN_INCHES*DOTS_PER_INCH) */
  30. #define Y_DOT_MAX          1274 /* NUM_Y_DOTS-1 */
  31. #define NUM_SLICES         3    /* smaller values run faster, use more memory */
  32. #define ROWS_PER_SLICE     425  /* (NUM_Y_DOTS+NUM_SLICES-1)/NUM_SLICES */
  33.  
  34. /* maze constants */
  35. #define MIN_DOTS_PER_ROOM_WALL  40
  36. #define NUM_COLUMNS             20   /* <= NUM_X_DOTS/MIN_DOTS_PER_ROOM_WALL */
  37. #define MAX_X                   40   /* 2*NUM_COLUMNS */
  38. #define MAX_X_PLUS_1            41   /* MAX_X+1 */
  39. #define NUM_ROWS                15   /* <= NUM_Y_DOTS/MIN_DOTS_PER_ROOM_WALL */
  40. #define MAX_Y                   30   /* 2*NUM_ROWS */
  41. #define MAX_Y_PLUS_1            31   /* MAX_Y+1 */
  42.     /* ((double) NUM_COLUMNS)/((double) NUM_ROWS) should be approximately
  43.        LENGTH_IN_INCHES/WIDTH_IN_INCHES.
  44.        Memory requirements and run time increase with NUM_COLUMNS*NUM_ROWS.
  45.     */
  46.  
  47. typedef struct pointtype_record
  48.           {
  49.             int x;
  50.             int y;
  51.           } pointtype;
  52.  
  53. typedef struct prime_rec_record  *prime_rec_ptr;
  54.  
  55. typedef struct prime_rec_record
  56.           {
  57.             double        x;
  58.             double        y;
  59.             double        z;
  60.             char          base_z;
  61.             prime_rec_ptr left;
  62.             prime_rec_ptr right;
  63.             prime_rec_ptr down;
  64.             prime_rec_ptr lesser_x;
  65.             prime_rec_ptr greater_x;
  66.           } prime_rec;
  67.  
  68. typedef struct row_type_record
  69.           {
  70.             unsigned char column [NUM_X_BYTES];
  71.           } row_type;
  72.  
  73. typedef row_type  *row_ptr_type;
  74.  
  75. typedef struct up_rec_record    *up_rec_ptr;
  76.  
  77. typedef struct up_rec_record
  78.           {
  79.             prime_rec_ptr up;
  80.             up_rec_ptr    next;
  81.             up_rec_ptr    previous;
  82.           } up_rec;
  83.  
  84. static void   add_room(void);
  85. static void   adjust_perspective(prime_rec_ptr *,prime_rec_ptr *,
  86.                prime_rec_ptr *,double *,double *,double *,double *,double *,
  87.                int *);
  88. static void   draw_line(int *,int *,int *,int *,int);
  89. static void   evaluate_and_transform(double *,double *,double *,double *,int *,
  90.                int *,double *,double *,prime_rec_ptr *,prime_rec_ptr *,
  91.                prime_rec_ptr *,double *,double *,double *,double *,double *,
  92.                int *);
  93. static double f(double,double);
  94.        void   main(void);
  95. static void   plot(prime_rec_ptr *,double *,double *,double *,double *,int *,
  96.                int *);
  97. static void   pset(int *,int *,int);
  98.  
  99. static unsigned char black [8] = {128, 64, 32, 16, 8, 4, 2, 1};
  100. static int           delta_x [4] [24];
  101. static int           delta_y [4] [24];
  102. static char          page [MAX_Y_PLUS_1] [MAX_X_PLUS_1];
  103. static int           r_n [8];
  104. static int           r_n_index_1;
  105. static int           r_n_index_2;
  106. static row_ptr_type  row_ptr [ROWS_PER_SLICE];
  107. static int           slice_y;
  108. static int           slice_y_start;
  109. static int           slice_y_stop;
  110. static int           tem_int;
  111. static unsigned char white [8] = {127, 191, 223, 239, 247, 251, 253, 254};
  112. static int           x;
  113. static double        x_max;
  114. static int           x_next;
  115. static int           x_wall_1;
  116. static int           y;
  117. static int           y_next;
  118. static int           y_wall_1;
  119.  
  120. void main(void)
  121.     {
  122.       static   unsigned char ascii_equivalent [6];
  123. #if EBCDIC
  124.       static   unsigned char *char_ptr;
  125. #endif
  126.       register int           column_num;
  127.       static   int           cursor_x;
  128.       static   char          cursor_x_prefix [3] = {'\033', '\052', '\160'};
  129.       static   char          cursor_x_suffix = '\130';
  130.       static   int           cursor_y;
  131.       static   char          cursor_y_prefix [3] = {'\033', '\052', '\160'};
  132.       static   char          cursor_y_suffix = '\131';
  133.       static   int           delta_index_1a;
  134.       static   int           delta_index_1b;
  135.       static   int           delta_index_1c;
  136.       static   int           delta_index_1d;
  137.       static   int           delta_index_2;
  138.       static   int           digit;
  139.       static   int           digit_num;
  140.       static   char          dpi_prefix [3] = {'\033', '\052', '\164'};
  141.       static   char          dpi_suffix = '\122';
  142.       register int           ending_column_num;
  143.       static   int           fatal_error;
  144.       static   char          formfeed = '\014';
  145.       static   char          landscape [5]
  146.                               = {'\033', '\046', '\154', '\061', '\117'};
  147.       static   char          logical_mode [5]
  148.                               = {'\033', '\052', '\162', '\060', '\106'};
  149.       static   int           max_y_out;
  150.       static   int           max_z_out;
  151.                FILE          *maze;
  152.       static   int           non_null_found;
  153.       static   int           num_bytes;
  154.       static   int           num_x_divisions;
  155.       static   int           num_y_divisions;
  156.       static   prime_rec_ptr prime_cornor;
  157.       static   prime_rec_ptr prime_head;
  158.       static   prime_rec_ptr prime_ptr;
  159.       static   prime_rec_ptr prime_tail;
  160.       static   char          raster_prefix [5]
  161.                               = {'\033', '\052', '\162', '\061', '\101'};
  162.       static   char          raster_suffix [4]
  163.                               = {'\033', '\052', '\162', '\102'};
  164.       static   double        rotation;
  165.       static   int           row_num;
  166.       static   char          row_prefix [3] = {'\033', '\052', '\142'};
  167.       static   char          row_suffix = '\127';
  168.       static   char          seed [256];
  169.       static   int           seed_length;
  170.       static   int           starting_column_num;
  171.       static   int           sum;
  172.       static   double        tilt;
  173.       static   double        x_min;
  174.       static   int           x_out;
  175.       static   double        x_prime_max;
  176.       static   double        y_max;
  177.       static   double        y_min;
  178.       static   int           y_out;
  179.       static   double        y_prime_max;
  180.       static   double        y_prime_min;
  181.       static   double        z_prime_max;
  182.       static   double        z_prime_min;
  183.  
  184.       fatal_error=FALSE;
  185.       printf("\n     The maze will be outputted to HP3DMAZE.\n\n");
  186.       printf("     Random number seed?  ");
  187.       gets(&seed[0]);
  188.       seed_length=strlen(&seed[0]);
  189.       for (r_n_index_1=0; r_n_index_1 < seed_length; ++r_n_index_1)
  190.         {
  191.           tem_int=(int) seed[r_n_index_1];
  192.           while (tem_int >= 29)
  193.              tem_int-=29;
  194.           r_n[r_n_index_1]=tem_int;
  195.         }
  196.       r_n_index_2=7;
  197.       while (r_n_index_1 > 0)
  198.         {
  199.            r_n_index_1--;
  200.            r_n[r_n_index_2]=r_n[r_n_index_1];
  201.            r_n_index_2--;
  202.         }
  203.       while (r_n_index_2 >= 0)
  204.         {
  205.           r_n[r_n_index_2]=19;
  206.           r_n_index_2--;
  207.         }
  208.       delta_x[0][0]=-1;
  209.       delta_y[0][0]=0;
  210.       delta_x[1][0]=0;
  211.       delta_y[1][0]=1;
  212.       delta_x[2][0]=1;
  213.       delta_y[2][0]=0;
  214.       delta_x[3][0]=0;
  215.       delta_y[3][0]=-1;
  216.       delta_index_2=0;
  217.       for (delta_index_1a=0; delta_index_1a < 4; ++delta_index_1a)
  218.         for (delta_index_1b=0; delta_index_1b < 4; ++delta_index_1b)
  219.           if (delta_index_1a != delta_index_1b)
  220.             for (delta_index_1c=0; delta_index_1c < 4; ++delta_index_1c)
  221.               if ((delta_index_1a != delta_index_1c)
  222.               &&  (delta_index_1b != delta_index_1c))
  223.                 for (delta_index_1d=0; delta_index_1d < 4; ++delta_index_1d)
  224.                   if ((delta_index_1a != delta_index_1d)
  225.                   &&  (delta_index_1b != delta_index_1d)
  226.                   &&  (delta_index_1c != delta_index_1d))
  227.                     {
  228.                       delta_x[delta_index_1a][delta_index_2]=delta_x[0][0];
  229.                       delta_y[delta_index_1a][delta_index_2]=delta_y[0][0];
  230.                       delta_x[delta_index_1b][delta_index_2]=delta_x[1][0];
  231.                       delta_y[delta_index_1b][delta_index_2]=delta_y[1][0];
  232.                       delta_x[delta_index_1c][delta_index_2]=delta_x[2][0];
  233.                       delta_y[delta_index_1c][delta_index_2]=delta_y[2][0];
  234.                       delta_x[delta_index_1d][delta_index_2]=delta_x[3][0];
  235.                       delta_y[delta_index_1d][delta_index_2]=delta_y[3][0];
  236.                       delta_index_2++;
  237.                     }
  238.       for (row_num=0; ((row_num < ROWS_PER_SLICE) && (! fatal_error));
  239.        ++row_num)
  240.         {
  241.           if ((row_ptr[row_num]=(row_type *) malloc(sizeof(row_type))) == NULL)
  242.             {
  243.               fatal_error=TRUE;
  244.               printf("\n     Fatal error:  out of memory\n");
  245.             }
  246.         }
  247.       if (! fatal_error)
  248.         {
  249.           max_y_out=X_DOT_MAX;
  250.           max_z_out=Y_DOT_MAX;
  251.           for (y_out=0; y_out <= MAX_Y; ++y_out)
  252.             for (x_out=0; x_out <= MAX_X; ++x_out)
  253.               page[y_out][x_out]='W';
  254.           sum=0;
  255.           for (digit_num=1; digit_num <= 3; ++digit_num)
  256.             {
  257.               digit=r_n[0];
  258.               r_n_index_1=0;
  259.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  260.                 {
  261.                   tem_int=r_n[r_n_index_2];
  262.                   r_n[r_n_index_1]=tem_int;
  263.                   digit+=tem_int;
  264.                   if (digit >= 29)
  265.                      digit-=29;
  266.                   r_n_index_1=r_n_index_2;
  267.                 }
  268.               r_n[7]=digit;
  269.               sum=29*sum+digit;
  270.             }
  271.           x=2*(sum % NUM_COLUMNS)+1;
  272.           sum=0;
  273.           for (digit_num=1; digit_num <= 3; ++digit_num)
  274.             {
  275.               digit=r_n[0];
  276.               r_n_index_1=0;
  277.               for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  278.                 {
  279.                   tem_int=r_n[r_n_index_2];
  280.                   r_n[r_n_index_1]=tem_int;
  281.                   digit+=tem_int;
  282.                   if (digit >= 29)
  283.                      digit-=29;
  284.                   r_n_index_1=r_n_index_2;
  285.                 }
  286.               r_n[7]=digit;
  287.               sum=29*sum+digit;
  288.             }
  289.           y=2*(sum % NUM_ROWS)+1;
  290.           add_room();
  291.           page[0][1]=' ';
  292.           page[MAX_Y][MAX_X-1]=' ';
  293.           x_min=1.0;
  294.           x_max=(double) MAX_Y;
  295.           x_max=2.0*x_max+5.0;
  296.           y_min=1.0;
  297.           y_max=(double) MAX_X;
  298.           y_max=2.0*y_max+5.0;
  299.           num_x_divisions=2*MAX_Y+5;
  300.           num_y_divisions=2*MAX_X+5;
  301.           prime_head=NULL;
  302.           rotation=20.0;
  303.           tilt=30.0;
  304.           evaluate_and_transform(&x_min,&x_max,&y_min,&y_max,&num_x_divisions,
  305.            &num_y_divisions,&rotation,&tilt,&prime_cornor,&prime_head,
  306.            &prime_tail,&x_prime_max,&y_prime_min,&y_prime_max,&z_prime_min,
  307.            &z_prime_max,&fatal_error);
  308.         }
  309.       if (! fatal_error)
  310.         adjust_perspective(&prime_cornor,&prime_head,&prime_tail,&x_prime_max,
  311.          &y_prime_min,&y_prime_max,&z_prime_min,&z_prime_max,&fatal_error);
  312.       if (! fatal_error)
  313.         {
  314.           maze=fopen("HP3DMAZE","wb");
  315.           fwrite(landscape,sizeof(landscape),1,maze);
  316.           fwrite(dpi_prefix,sizeof(dpi_prefix),1,maze);
  317.           sprintf((char *) ascii_equivalent,"%d",DOTS_PER_INCH);
  318. #if EBCDIC
  319.           char_ptr=&(ascii_equivalent[0]);
  320.           while (*char_ptr)
  321.             {
  322.               (*char_ptr)-=192;
  323.               char_ptr++;
  324.             }
  325. #endif
  326.           fwrite(&(ascii_equivalent[0]),strlen((char *) ascii_equivalent),1,
  327.            maze);
  328.           fwrite(&dpi_suffix,sizeof(dpi_suffix),1,maze);
  329.           fwrite(logical_mode,sizeof(logical_mode),1,maze);
  330.           slice_y_start=0;
  331.           while (slice_y_start <= Y_DOT_MAX)
  332.             {
  333.               slice_y_stop=slice_y_start+ROWS_PER_SLICE-1;
  334.               if (slice_y_stop > Y_DOT_MAX)
  335.                 slice_y_stop=Y_DOT_MAX;
  336.               for (row_num=0; row_num < ROWS_PER_SLICE; row_num++)
  337.                 for (column_num=0; column_num <= X_BYTE_MAX; column_num++)
  338.                  row_ptr[row_num]->column[column_num]=0;
  339.               plot(&prime_tail,&y_prime_min,&y_prime_max,&z_prime_min,
  340.                &z_prime_max,&max_y_out,&max_z_out);
  341.               row_num=0;
  342.               for (slice_y=slice_y_start; slice_y <= slice_y_stop; slice_y++)
  343.                 {
  344.                   starting_column_num=0;
  345.                   non_null_found=FALSE;
  346.                   while ((starting_column_num <= X_BYTE_MAX)
  347.                   &&     (! non_null_found))
  348.                     if (row_ptr[row_num]->column[starting_column_num] == 0)
  349.                       starting_column_num++;
  350.                     else
  351.                       non_null_found=TRUE;
  352.                   if (non_null_found)
  353.                     {
  354.                       non_null_found=FALSE;
  355.                       ending_column_num=X_BYTE_MAX;
  356.                       while ((ending_column_num >= 0) && (! non_null_found))
  357.                         if (row_ptr[row_num]->column[ending_column_num] == 0)
  358.                           ending_column_num--;
  359.                         else
  360.                           non_null_found=TRUE;
  361.                       fwrite(cursor_x_prefix,sizeof(cursor_x_prefix),1,maze);
  362.                       cursor_x=DOTS_PER_STROKE*8*starting_column_num;
  363.                       sprintf((char *) ascii_equivalent,"%d",cursor_x);
  364. #if EBCDIC
  365.                       char_ptr=&(ascii_equivalent[0]);
  366.                       while (*char_ptr)
  367.                         {
  368.                           (*char_ptr)-=192;
  369.                           char_ptr++;
  370.                         }
  371. #endif
  372.                       fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
  373.                        maze);
  374.                       fwrite(&cursor_x_suffix,sizeof(cursor_x_suffix),1,maze);
  375.                       fwrite(cursor_y_prefix,sizeof(cursor_y_prefix),1,maze);
  376.                       cursor_y=DOTS_PER_STROKE*slice_y;
  377.                       sprintf(ascii_equivalent,"%d",cursor_y);
  378. #if EBCDIC
  379.                       char_ptr=&(ascii_equivalent[0]);
  380.                       while (*char_ptr)
  381.                         {
  382.                           (*char_ptr)-=192;
  383.                           char_ptr++;
  384.                         }
  385. #endif
  386.                       fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
  387.                        maze);
  388.                       fwrite(&cursor_y_suffix,sizeof(cursor_y_suffix),1,maze);
  389.                       fwrite(raster_prefix,sizeof(raster_prefix),1,maze);
  390.                       fwrite(row_prefix,sizeof(row_prefix),1,maze);
  391.                       num_bytes=ending_column_num-starting_column_num+1;
  392.                       sprintf(ascii_equivalent,"%d",num_bytes);
  393. #if EBCDIC
  394.                       char_ptr=&(ascii_equivalent[0]);
  395.                       while (*char_ptr)
  396.                         {
  397.                           (*char_ptr)-=192;
  398.                           char_ptr++;
  399.                         }
  400. #endif
  401.                       fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
  402.                        maze);
  403.                       fwrite(&row_suffix,sizeof(row_suffix),1,maze);
  404.                       fwrite(&(row_ptr[row_num]->column[starting_column_num]),
  405.                        num_bytes,1,maze);
  406.                       fwrite(raster_suffix,sizeof(raster_suffix),1,maze);
  407.                     }
  408.                   row_num++;
  409.                 }
  410.               slice_y_start+=ROWS_PER_SLICE;
  411.             }
  412.           fwrite(&formfeed,sizeof(formfeed),1,maze);
  413.           fclose(maze);
  414.           while (prime_head != NULL)
  415.             {
  416.               prime_ptr=prime_head->greater_x;
  417.               free(prime_head);
  418.               prime_head=prime_ptr;
  419.             }
  420.           for (row_num=0; row_num < ROWS_PER_SLICE; ++row_num)
  421.             free(row_ptr[row_num]);
  422.         }
  423.     }
  424.  
  425. static void add_room()
  426.     {
  427.       unsigned char delta_index_1;
  428.       unsigned char delta_index_2;
  429.  
  430.       page[y][x]=' ';
  431.       delta_index_1=0;
  432.       do
  433.         {
  434.           delta_index_2=(unsigned char) r_n[0];
  435.           r_n_index_1=0;
  436.           for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
  437.             {
  438.               tem_int=r_n[r_n_index_2];
  439.               r_n[r_n_index_1]=tem_int;
  440.               delta_index_2+=(unsigned char) tem_int;
  441.               if (delta_index_2 >= 29)
  442.                 delta_index_2-=29;
  443.               r_n_index_1=r_n_index_2;
  444.             }
  445.           r_n[7]=delta_index_2;
  446.         }
  447.       while (delta_index_2 >= 24);
  448.       while (delta_index_1 < 4)
  449.         {
  450.           x_next=x+2*delta_x[delta_index_1][delta_index_2];
  451.           if ((x_next <= 0) || (x_next >= MAX_X))
  452.             delta_index_1++;
  453.           else
  454.             {
  455.               y_next=y+2*delta_y[delta_index_1][delta_index_2];
  456.               if ((y_next <= 0) || (y_next >= MAX_Y))
  457.                 delta_index_1++;
  458.               else
  459.                 if (page[y_next][x_next] == 'W')
  460.                   {
  461.                     if (x == x_next)
  462.                       {
  463.                         y_wall_1=(y+y_next)/2;
  464.                         page[y_wall_1][x_next]=' ';
  465.                       }
  466.                     else
  467.                       {
  468.                         x_wall_1=(x+x_next)/2;
  469.                         page[y_next][x_wall_1]=' ';
  470.                       }
  471.                     x=x_next;
  472.                     y=y_next;
  473.                     add_room();
  474.                     x-=2*delta_x[delta_index_1][delta_index_2];
  475.                     y-=2*delta_y[delta_index_1][delta_index_2];
  476.                   }
  477.                 else
  478.                   delta_index_1++;
  479.             }
  480.         }
  481.     }
  482.  
  483. static double f(x,y)
  484.   double x;
  485.   double y;
  486.     {
  487.       register int    x_out;
  488.       register int    y_out;
  489.       static   double z;
  490.  
  491.       y_out=((int) x)-2;
  492.       if (y_out < 0)
  493.         z=0.0;
  494.       else
  495.         if (y_out > 2*MAX_Y+1)
  496.           z=0.0;
  497.         else
  498.           {
  499.             x_out=((int) y)-2;
  500.             if (x_out < 0)
  501.               z=0.0;
  502.             else
  503.               if (x_out > 2*MAX_X+1)
  504.                 z=0.0;
  505.               else
  506.                 if (page[y_out/2][x_out/2] == 'W')
  507.                   z=7.0;
  508.                 else
  509.                   z=0.0;
  510.           }
  511.       return(z);
  512.     }
  513.  
  514. static void evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
  515.  num_y_divisions,rotation,tilt,prime_cornor,prime_head,prime_tail,x_prime_max,
  516.  y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
  517.   double        *x_min;
  518.   double        *x_max;
  519.   double        *y_min;
  520.   double        *y_max;
  521.   int           *num_x_divisions;
  522.   int           *num_y_divisions;
  523.   double        *rotation;
  524.   double        *tilt;
  525.   prime_rec_ptr *prime_cornor;
  526.   prime_rec_ptr *prime_head;
  527.   prime_rec_ptr *prime_tail;
  528.   double        *x_prime_max;
  529.   double        *y_prime_min;
  530.   double        *y_prime_max;
  531.   double        *z_prime_min;
  532.   double        *z_prime_max;
  533.   int           *fatal_error;
  534.     {
  535.       static   double        cos_rotation;
  536.       static   double        cos_tilt;
  537.       static   double        delta_x;
  538.       static   double        delta_y;
  539.       static   prime_rec_ptr last_prime_ptr;
  540.       static   prime_rec_ptr prime_ptr;
  541.       static   double        radians;
  542.       static   double        radians_per_degree;
  543.       static   prime_rec_ptr left;
  544.       static   double        sin_rotation;
  545.       static   double        sin_tilt;
  546.       static   up_rec_ptr    up_head;
  547.       static   up_rec_ptr    up_ptr;
  548.       static   up_rec_ptr    up_tail;
  549.       static   double        x;
  550.       register int           x_division_num;
  551.       static   double        y;
  552.       register int           y_division_num;
  553.       static   double        x_rotated;
  554.       static   double        z;
  555.  
  556.       radians_per_degree=atan((double) 1.0)/45.0;
  557.       radians=(*tilt)*radians_per_degree;
  558.       cos_tilt=cos(radians);
  559.       sin_tilt=sin(radians);
  560.       radians=(*rotation)*radians_per_degree;
  561.       cos_rotation=cos(radians);
  562.       sin_rotation=sin(radians);
  563.       z=f(*x_min,*y_min);
  564.       x_rotated=(*x_min)*cos_rotation+(*y_min)*sin_rotation;
  565.       (*y_prime_min)=-(*x_min)*sin_rotation+(*y_min)*cos_rotation;
  566.       (*z_prime_min)=-x_rotated*sin_tilt+z*cos_tilt;
  567.       (*x_prime_max)=x_rotated*cos_tilt+z*sin_tilt;
  568.       (*y_prime_max)=(*y_prime_min);
  569.       (*z_prime_max)=(*z_prime_min);
  570.       last_prime_ptr=NULL;
  571.       delta_x=(double) (*num_x_divisions);
  572.       delta_x=((*x_max)-(*x_min))/delta_x;
  573.       delta_y=(double) (*num_y_divisions);
  574.       delta_y=((*y_max)-(*y_min))/delta_y;
  575.       up_head=NULL;
  576.       up_tail=NULL;
  577.       for (y_division_num=1;
  578.        ((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
  579.        ++y_division_num)
  580.         {
  581.           if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
  582.             {
  583.               *fatal_error=TRUE;
  584.               printf("\n     Fatal error:  out of memory\n");
  585.             }
  586.           else
  587.             {
  588.               up_ptr->up=NULL;
  589.               if (up_head == NULL)
  590.                 {
  591.                   up_head=up_ptr;
  592.                   up_ptr->previous=NULL;
  593.                 }
  594.               else
  595.                 {
  596.                   up_tail->next=up_ptr;
  597.                   up_ptr->previous=up_tail;
  598.                 }
  599.               up_ptr->next=NULL;
  600.               up_tail=up_ptr;
  601.             }
  602.         }
  603.       x=(*x_min);
  604.       for (x_division_num=1;
  605.        ((x_division_num <= (*num_x_divisions)) && (! *fatal_error));
  606.        ++x_division_num)
  607.         {
  608.           left=NULL;
  609.           up_ptr=up_head;
  610.           y=(*y_min);
  611.           for (y_division_num=1;
  612.            ((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
  613.            ++y_division_num)
  614.             {
  615.               z=f(x,y);
  616.               if ((prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
  617.                == NULL)
  618.                 {
  619.                   *fatal_error=TRUE;
  620.                   printf("\n     Fatal error:  out of memory\n");
  621.                 }
  622.               else
  623.                 {
  624.                   prime_ptr->left=left;
  625.                   if (z > 0.0)
  626.                     prime_ptr->base_z=(char) 1;
  627.                   else
  628.                     prime_ptr->base_z=(char) 0;
  629.                   if (left != NULL)
  630.                     left->right=prime_ptr;
  631.                   if (up_ptr->up != NULL)
  632.                     up_ptr->up->down=prime_ptr;
  633.                   x_rotated=x*cos_rotation+y*sin_rotation;
  634.                   prime_ptr->y=-x*sin_rotation+y*cos_rotation;
  635.                   prime_ptr->x=x_rotated*cos_tilt+z*sin_tilt;
  636.                   prime_ptr->z=-x_rotated*sin_tilt+z*cos_tilt;
  637.                   if (prime_ptr->x > (*x_prime_max))
  638.                     (*x_prime_max)=prime_ptr->x;
  639.                   if (prime_ptr->y < (*y_prime_min))
  640.                     (*y_prime_min)=prime_ptr->y;
  641.                   if (prime_ptr->y > (*y_prime_max))
  642.                     (*y_prime_max)=prime_ptr->y;
  643.                   if (prime_ptr->z < (*z_prime_min))
  644.                     (*z_prime_min)=prime_ptr->z;
  645.                   if (prime_ptr->z > (*z_prime_max))
  646.                     (*z_prime_max)=prime_ptr->z;
  647.                   prime_ptr->lesser_x=NULL;
  648.                   if (last_prime_ptr == NULL)
  649.                     {
  650.                       (*prime_tail)=prime_ptr;
  651.                       (*prime_cornor)=prime_ptr;
  652.                       prime_ptr->greater_x=NULL;
  653.                     }
  654.                   else
  655.                     {
  656.                       (*prime_head)->lesser_x=prime_ptr;
  657.                       prime_ptr->greater_x=(*prime_head);
  658.                     }
  659.                   (*prime_head)=prime_ptr;
  660.                   left=prime_ptr;
  661.                   up_ptr->up=prime_ptr;
  662.                   up_ptr=up_ptr->next;
  663.                   last_prime_ptr=prime_ptr;
  664.                   y+=delta_y;
  665.                 }
  666.             }
  667.           if (! *fatal_error)
  668.             {
  669.               left->right=NULL;
  670.               x+=delta_x;
  671.             }
  672.         }
  673.       if (! *fatal_error)
  674.         while (up_head != NULL)
  675.           {
  676.             up_head->up->down=NULL;
  677.             up_ptr=up_head->next;
  678.             free(up_head);
  679.             up_head=up_ptr;
  680.           }
  681.     }
  682.  
  683. static void adjust_perspective(prime_cornor,prime_head,prime_tail,x_prime_max,
  684.  y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
  685.   prime_rec_ptr *prime_cornor;
  686.   prime_rec_ptr *prime_head;
  687.   prime_rec_ptr *prime_tail;
  688.   double        *x_prime_max;
  689.   double        *y_prime_min;
  690.   double        *y_prime_max;
  691.   double        *z_prime_min;
  692.   double        *z_prime_max;
  693.   int           *fatal_error;
  694.     {
  695.       static   double        delta_x;
  696.       static   double        delta_y;
  697.       static   double        delta_z;
  698.       register int           finished;
  699.       static   prime_rec_ptr last_prime_ptr;
  700.       static   prime_rec_ptr left;
  701.       static   prime_rec_ptr new_prime_head;
  702.       static   prime_rec_ptr new_prime_ptr;
  703.       static   prime_rec_ptr new_prime_tail;
  704.       static   prime_rec_ptr next_prime_row;
  705.       static   prime_rec_ptr prime_column;
  706.       static   prime_rec_ptr prime_ptr;
  707.       static   prime_rec_ptr prime_row;
  708.       static   up_rec_ptr    up_head;
  709.       static   up_rec_ptr    up_ptr;
  710.       static   up_rec_ptr    up_tail;
  711.       static   double        x_eye;
  712.       static   double        y_center;
  713.       static   double        z_center;
  714.  
  715.       if (((*y_prime_max)-(*y_prime_min)) > ((*z_prime_max)-(*z_prime_min)))
  716.         x_eye=2.0*((*y_prime_max)-(*y_prime_min))+(*x_prime_max);
  717.       else
  718.         x_eye=2.0*((*z_prime_max)-(*z_prime_min))+(*x_prime_max);
  719.       if (x_eye != (*x_prime_max))
  720.         {
  721.           up_head=NULL;
  722.           up_tail=NULL;
  723.           prime_column=(*prime_cornor);
  724.           while ((prime_column != NULL) && (! *fatal_error))
  725.             {
  726.               if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
  727.                 {
  728.                   *fatal_error=TRUE;
  729.                   printf("\n     Fatal error:  out of memory\n");
  730.                 }
  731.               else
  732.                 {
  733.                   up_ptr->up=NULL;
  734.                   if (up_head == NULL)
  735.                     {
  736.                       up_head=up_ptr;
  737.                       up_ptr->previous=NULL;
  738.                     }
  739.                   else
  740.                     {
  741.                       up_tail->next=up_ptr;
  742.                       up_ptr->previous=up_tail;
  743.                     }
  744.                   up_ptr->next=NULL;
  745.                   up_tail=up_ptr;
  746.                   prime_column=prime_column->right;
  747.                 }
  748.             }
  749.           y_center=(double) ((*y_prime_max)+(*y_prime_min))/2.0;
  750.           z_center=(double) ((*z_prime_max)+(*z_prime_min))/2.0;
  751.           last_prime_ptr=NULL;
  752.           new_prime_head=NULL;
  753.           new_prime_tail=NULL;
  754.           prime_row=(*prime_cornor);
  755.           while ((prime_row != NULL) && (! *fatal_error))
  756.             {
  757.               left=NULL;
  758.               up_ptr=up_head;
  759.               next_prime_row=prime_row->down;
  760.               prime_column=prime_row;
  761.               while ((prime_column != NULL) && (! *fatal_error))
  762.                 {
  763.                   if ((new_prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
  764.                    == NULL)
  765.                     {
  766.                       *fatal_error=TRUE;
  767.                       printf("\n     Fatal error:  out of memory\n");
  768.                     }
  769.                   else
  770.                     {
  771.                       new_prime_ptr->left=left;
  772.                       new_prime_ptr->base_z=prime_column->base_z;
  773.                       if (left != NULL)
  774.                         left->right=new_prime_ptr;
  775.                       if (up_ptr->up != NULL)
  776.                         up_ptr->up->down=new_prime_ptr;
  777.                       delta_x=prime_column->x-x_eye;
  778.                       delta_y=prime_column->y-y_center;
  779.                       delta_z=prime_column->z-z_center;
  780.                       new_prime_ptr->x
  781.                        =sqrt(delta_x*delta_x+delta_y*delta_y+delta_z*delta_z);
  782.                       new_prime_ptr->y
  783.                        =y_center+(double)(prime_column->y-y_center)
  784.                        *(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
  785.                       new_prime_ptr->z
  786.                        =z_center+(double)(prime_column->z-z_center)
  787.                        *(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
  788.                       if (last_prime_ptr == NULL)
  789.                         {
  790.                           new_prime_head=new_prime_ptr;
  791.                           new_prime_tail=new_prime_ptr;
  792.                           new_prime_ptr->lesser_x=NULL;
  793.                           new_prime_ptr->greater_x=NULL;
  794.                         }
  795.                       else
  796.                         if (new_prime_ptr->x < last_prime_ptr->x)
  797.                           {
  798.                             finished=FALSE;
  799.                             while (! finished)
  800.                               {
  801.                                 last_prime_ptr=last_prime_ptr->lesser_x;
  802.                                 if (last_prime_ptr == NULL)
  803.                                   finished=TRUE;
  804.                                 else
  805.                                   {
  806.                                     if (new_prime_ptr->x >= last_prime_ptr->x)
  807.                                       finished=TRUE;
  808.                                   }
  809.                               }
  810.                             new_prime_ptr->lesser_x=last_prime_ptr;
  811.                             if (last_prime_ptr == NULL)
  812.                               {
  813.                                 new_prime_head->lesser_x=new_prime_ptr;
  814.                                 new_prime_ptr->greater_x=new_prime_head;
  815.                                 new_prime_head=new_prime_ptr;
  816.                               }
  817.                             else
  818.                               {
  819.                                 new_prime_ptr->greater_x
  820.                                  =last_prime_ptr->greater_x;
  821.                                 last_prime_ptr->greater_x->lesser_x
  822.                                  =new_prime_ptr;
  823.                                 last_prime_ptr->greater_x=new_prime_ptr;
  824.                               }
  825.                           }
  826.                         else
  827.                           {
  828.                             finished=FALSE;
  829.                             while (! finished)
  830.                               {
  831.                                 last_prime_ptr=last_prime_ptr->greater_x;
  832.                                 if (last_prime_ptr == NULL)
  833.                                   finished=TRUE;
  834.                                 else
  835.                                   {
  836.                                     if (new_prime_ptr->x <= last_prime_ptr->x)
  837.                                       finished=TRUE;
  838.                                   }
  839.                               }
  840.                             new_prime_ptr->greater_x=last_prime_ptr;
  841.                             if (last_prime_ptr == NULL)
  842.                               {
  843.                                 new_prime_tail->greater_x=new_prime_ptr;
  844.                                 new_prime_ptr->lesser_x=new_prime_tail;
  845.                                 new_prime_tail=new_prime_ptr;
  846.                               }
  847.                             else
  848.                               {
  849.                                 new_prime_ptr->lesser_x
  850.                                  =last_prime_ptr->lesser_x;
  851.                                 last_prime_ptr->lesser_x->greater_x
  852.                                  =new_prime_ptr;
  853.                                 last_prime_ptr->lesser_x=new_prime_ptr;
  854.                               }
  855.                           }
  856.                     }
  857.                   if (! *fatal_error)
  858.                     {
  859.                       left=new_prime_ptr;
  860.                       up_ptr->up=new_prime_ptr;
  861.                       up_ptr=up_ptr->next;
  862.                       last_prime_ptr=new_prime_ptr;
  863.                       prime_ptr=prime_column->right;
  864.                       free(prime_column);
  865.                       prime_column=prime_ptr;
  866.                     }
  867.                 }
  868.               if (! *fatal_error)
  869.                 {
  870.                   left->right=NULL;
  871.                   prime_row=next_prime_row;
  872.                 }
  873.             }
  874.           if (! *fatal_error)
  875.             {
  876.               (*prime_head)=new_prime_head;
  877.               (*prime_tail)=new_prime_tail;
  878.               while (up_head != NULL)
  879.                 {
  880.                   up_head->up->down=NULL;
  881.                   up_ptr=up_head->next;
  882.                   free(up_head);
  883.                   up_head=up_ptr;
  884.                 }
  885.             }
  886.         }
  887.     }
  888.  
  889. static void pset(x,y,shading)
  890.   int *x;
  891.   int *y;
  892.   int shading;
  893.     {
  894.       register int bit_num;
  895.       register int byte_num;
  896.       static   int dot;
  897.       static   int slice_y;
  898.  
  899.       if ((*y) >= slice_y_start)
  900.         {
  901.           if ((*y) <= slice_y_stop)
  902.             {
  903.               byte_num=(*x)/8;
  904.               bit_num=(*x)-8*byte_num;
  905.               switch (shading)
  906.                 {
  907.                   case 0:
  908.                     switch ((*y) % 4)
  909.                       {
  910.                         case 0:
  911.                           if (((*x) % 4) == 3)
  912.                             dot=TRUE;
  913.                           else
  914.                             dot=FALSE;
  915.                           break;
  916.                         case 1:
  917.                           if (((*x) % 4) == 1)
  918.                             dot=TRUE;
  919.                           else
  920.                             dot=FALSE;
  921.                           break;
  922.                         case 2:
  923.                           if (((*x) % 4) == 2)
  924.                             dot=TRUE;
  925.                           else
  926.                             dot=FALSE;
  927.                           break;
  928.                         default:
  929.                           if (((*x) % 4) == 0)
  930.                             dot=TRUE;
  931.                           else
  932.                             dot=FALSE;
  933.                           break;
  934.                       }
  935.                     break;
  936.                   case 1:
  937.                     if ((*y) % 2)
  938.                       if (((*x) % 4) == 1)
  939.                         dot=TRUE;
  940.                       else
  941.                         dot=FALSE;
  942.                     else
  943.                       if ((*x) % 2)
  944.                         dot=FALSE;
  945.                       else
  946.                         dot=TRUE;
  947.                     break;
  948.                   case 2:
  949.                     if ((*y) % 2)
  950.                       if ((*x) % 2)
  951.                         dot=TRUE;
  952.                       else
  953.                         dot=FALSE;
  954.                     else
  955.                       if ((*x) % 2)
  956.                         dot=FALSE;
  957.                       else
  958.                         dot=TRUE;
  959.                     break;
  960.                   default:
  961.                     dot=TRUE;
  962.                     break;
  963.                 };
  964.               slice_y=(*y)-slice_y_start;
  965.               if (dot)
  966.                 row_ptr[slice_y]->column[byte_num]
  967.                  =(row_ptr[slice_y]->column[byte_num] | black[bit_num]);
  968.               else
  969.                 row_ptr[slice_y]->column[byte_num]
  970.                  =(row_ptr[slice_y]->column[byte_num] & white[bit_num]);
  971.             }
  972.         }
  973.     }
  974.  
  975. static void draw_line(x1,y1,x2,y2,shading)
  976.   int *x1;
  977.   int *y1;
  978.   int *x2;
  979.   int *y2;
  980.   int shading;
  981.     {
  982.       static   int error;
  983.       static   int error_prime_x;
  984.       static   int error_prime_y;
  985.       register int permissible_delta_x;
  986.       register int permissible_delta_y;
  987.       static   int x;
  988.       static   int x_diff;
  989.       static   int y;
  990.       static   int y_diff;
  991.  
  992.       if ((*x2) >= (*x1))
  993.         permissible_delta_x=1;
  994.       else
  995.         permissible_delta_x=-1;
  996.       if ((*y2) >= (*y1))
  997.         permissible_delta_y=1;
  998.       else
  999.         permissible_delta_y=-1;
  1000.       x=(*x1);
  1001.       y=(*y1);
  1002.       x_diff=(*x2)-(*x1);
  1003.       y_diff=(*y2)-(*y1);
  1004.       error=0;
  1005.       pset(&x,&y,shading);
  1006.       while ((x != (*x2)) || (y != (*y2)))
  1007.         {
  1008.           error_prime_x=error+permissible_delta_x*y_diff;
  1009.           error_prime_y=error-permissible_delta_y*x_diff;
  1010.           if (abs(error_prime_x) <= abs(error_prime_y))
  1011.             {
  1012.               x+=permissible_delta_x;
  1013.               error=error_prime_x;
  1014.             }
  1015.           else
  1016.             {
  1017.               y+=permissible_delta_y;
  1018.               error=error_prime_y;
  1019.             }
  1020.           pset(&x,&y,shading);
  1021.         }
  1022.     }
  1023.  
  1024. static void plot(prime_tail,y_prime_min,y_prime_max,z_prime_min,z_prime_max,
  1025.  max_y_out,max_z_out)
  1026.   prime_rec_ptr *prime_tail;
  1027.   double *y_prime_min;
  1028.   double *y_prime_max;
  1029.   double *z_prime_min;
  1030.   double *z_prime_max;
  1031.   int    *max_y_out;
  1032.   int    *max_z_out;
  1033.     {
  1034.       static   pointtype     box [4];
  1035.       static   long          box_delta_x;
  1036.       static   long          box_delta_y;
  1037.       register int           box_num_1;
  1038.       register int           box_num_2;
  1039.       static   long          box_x_intercept;
  1040.       static   int           box_x1;
  1041.       static   int           box_x2;
  1042.       static   int           box_y_max;
  1043.       static   int           box_y_min;
  1044.       static   long          box_y_offset;
  1045.       static   int           box_y1;
  1046.       static   int           intercept_count_mod_2;
  1047.       static   int           line_x1;
  1048.       static   int           line_x2;
  1049.       static   int           line_y1;
  1050.       static   int           line_y2;
  1051.       static   double        pixels_per_unit;
  1052.       static   prime_rec_ptr prime_ptr;
  1053.       static   int           shading;
  1054.       static   double        y_offset;
  1055.       static   double        y_out_max;
  1056.       static   double        z_offset;
  1057.       static   double        z_out_max;
  1058.  
  1059.       y_out_max=(double) (*max_y_out);
  1060.       z_out_max=(double) (*max_z_out);
  1061.       if (z_out_max*((*y_prime_max)-(*y_prime_min))
  1062.        > y_out_max*((*z_prime_max)-(*z_prime_min)))
  1063.         {
  1064.           pixels_per_unit=y_out_max/((*y_prime_max)-(*y_prime_min));
  1065.           y_offset=0.0;
  1066.           z_offset
  1067.            =-(z_out_max-pixels_per_unit*((*z_prime_max)-(*z_prime_min)))/2.0;
  1068.         }
  1069.       else
  1070.         if (z_out_max*((*y_prime_max)-(*y_prime_min))
  1071.          < y_out_max*((*z_prime_max)-(*z_prime_min)))
  1072.           {
  1073.             pixels_per_unit=z_out_max/((*z_prime_max)-(*z_prime_min));
  1074.             y_offset
  1075.              =(y_out_max-pixels_per_unit*((*y_prime_max)-(*y_prime_min)))/2.0;
  1076.             z_offset=0.0;
  1077.           }
  1078.         else
  1079.           /* plot degenerates to a single point */
  1080.           {
  1081.             pixels_per_unit=1.0;
  1082.             y_offset=y_out_max/2.0;
  1083.             z_offset=-z_out_max/2.0;
  1084.           }
  1085.       prime_ptr=(*prime_tail);
  1086.       while ((prime_ptr != NULL))
  1087.         {
  1088.           if ((prime_ptr->right != NULL))
  1089.             {
  1090.               if ((prime_ptr->down != NULL))
  1091.                 {
  1092.                   box[0].x=(int) (y_offset+pixels_per_unit
  1093.                    *(prime_ptr->y-(*y_prime_min)));
  1094.                   box[0].y=(int) (z_offset+z_out_max-pixels_per_unit
  1095.                    *(prime_ptr->z-(*z_prime_min)));
  1096.                   box[1].x=(int) (y_offset+pixels_per_unit
  1097.                    *(prime_ptr->right->y-(*y_prime_min)));
  1098.                   box[1].y=(int) (z_offset+z_out_max-pixels_per_unit
  1099.                    *(prime_ptr->right->z-(*z_prime_min)));
  1100.                   box[3].x=(int) (y_offset+pixels_per_unit
  1101.                    *(prime_ptr->down->y-(*y_prime_min)));
  1102.                   box[3].y=(int) (z_offset+z_out_max-pixels_per_unit
  1103.                    *(prime_ptr->down->z-(*z_prime_min)));
  1104.                   box[2].x=(int) (y_offset+pixels_per_unit
  1105.                    *(prime_ptr->down->right->y-(*y_prime_min)));
  1106.                   box[2].y=(int) (z_offset+z_out_max-pixels_per_unit
  1107.                    *(prime_ptr->down->right->z-(*z_prime_min)));
  1108.                   box_y_min=box[0].y;
  1109.                   box_y_max=box_y_min;
  1110.                   if ((prime_ptr->base_z == (char) 1)
  1111.                   &&  (prime_ptr->right->base_z == (char) 1)
  1112.                   &&  (prime_ptr->down->base_z == (char) 1)
  1113.                   &&  (prime_ptr->down->right->base_z == (char) 1))
  1114.                     shading=0;
  1115.                   else
  1116.                     if ((prime_ptr->base_z == (char) 0)
  1117.                     &&  (prime_ptr->right->base_z == (char) 0)
  1118.                     &&  (prime_ptr->down->base_z == (char) 0)
  1119.                     &&  (prime_ptr->down->right->base_z == (char) 0))
  1120.                       shading=1;
  1121.                     else
  1122.                       if ((prime_ptr->base_z == (char) 1)
  1123.                       &&  (prime_ptr->right->base_z == (char) 1)
  1124.                       &&  (prime_ptr->down->base_z == (char) 0)
  1125.                       &&  (prime_ptr->down->right->base_z == (char) 0))
  1126.                         shading=2;
  1127.                       else
  1128.                         if ((prime_ptr->base_z == (char) 1)
  1129.                         &&  (prime_ptr->right->base_z == (char) 0)
  1130.                         &&  (prime_ptr->down->base_z == (char) 1)
  1131.                         &&  (prime_ptr->down->right->base_z == (char) 0))
  1132.                           shading=3;
  1133.                         else
  1134.                           if ((prime_ptr->down->down == NULL)
  1135.                           &&  (prime_ptr->base_z == (char) 0))
  1136.                             shading=1;
  1137.                           else
  1138.                             shading=2;
  1139.                   for (box_num_1=1; box_num_1 < 4; ++box_num_1)
  1140.                     {
  1141.                       if (box[box_num_1].y < box_y_min)
  1142.                         box_y_min=box[box_num_1].y;
  1143.                       if (box[box_num_1].y > box_y_max)
  1144.                         box_y_max=box[box_num_1].y;
  1145.                     }
  1146.                   for (box_y1=box_y_min; box_y1 <= box_y_max; ++box_y1)
  1147.                     {
  1148.                       intercept_count_mod_2=0;
  1149.                       box_num_2=1;
  1150.                       for (box_num_1=0; box_num_1 < 4; ++box_num_1)
  1151.                         {
  1152.                           if (box[box_num_1].y >= box_y1)
  1153.                             {
  1154.                               if (box_y1 > box[box_num_2].y)
  1155.                                 {
  1156.                                   box_delta_y=box[box_num_2].y-box[box_num_1].y;
  1157.                                   box_delta_x=box[box_num_2].x-box[box_num_1].x;
  1158.                                   box_y_offset=box_y1-box[box_num_1].y;
  1159.                                   box_x_intercept=box[box_num_1].x;
  1160.                                   box_x1=(int) ((box_delta_x*box_y_offset)
  1161.                                    /box_delta_y+box_x_intercept);
  1162.                                   if (intercept_count_mod_2 == 0)
  1163.                                     box_x2=box_x1;
  1164.                                   else
  1165.                                     {
  1166.                                       if (box_x1 < box_x2)
  1167.                                         {
  1168.                                           line_x1=box_x1;
  1169.                                           line_x2=box_x2;
  1170.                                         }
  1171.                                       else
  1172.                                         {
  1173.                                           line_x1=box_x2;
  1174.                                           line_x2=box_x1;
  1175.                                         }
  1176.                                       pset(&line_x1,&box_y1,shading);
  1177.                                       while (line_x1 < line_x2)
  1178.                                         {
  1179.                                           line_x1++;
  1180.                                           pset(&line_x1,&box_y1,shading);
  1181.                                         }
  1182.                                     }
  1183.                                   intercept_count_mod_2=1-intercept_count_mod_2;
  1184.                                 }
  1185.                             }
  1186.                           else
  1187.                             {
  1188.                               if (box_y1 <= box[box_num_2].y)
  1189.                                 {
  1190.                                   box_delta_y=box[box_num_2].y-box[box_num_1].y;
  1191.                                   box_delta_x=box[box_num_2].x-box[box_num_1].x;
  1192.                                   box_y_offset=box_y1-box[box_num_1].y;
  1193.                                   box_x_intercept=box[box_num_1].x;
  1194.                                   box_x1=(int) ((box_delta_x*box_y_offset)
  1195.                                    /box_delta_y+box_x_intercept);
  1196.                                   if (intercept_count_mod_2 == 0)
  1197.                                     box_x2=box_x1;
  1198.                                   else
  1199.                                     {
  1200.                                       if (box_x1 < box_x2)
  1201.                                         {
  1202.                                           line_x1=box_x1;
  1203.                                           line_x2=box_x2;
  1204.                                         }
  1205.                                       else
  1206.                                         {
  1207.                                           line_x1=box_x2;
  1208.                                           line_x2=box_x1;
  1209.                                         }
  1210.                                       pset(&line_x1,&box_y1,shading);
  1211.                                       while (line_x1 < line_x2)
  1212.                                         {
  1213.                                           line_x1++;
  1214.                                           pset(&line_x1,&box_y1,shading);
  1215.                                         }
  1216.                                     }
  1217.                                   intercept_count_mod_2=1-intercept_count_mod_2;
  1218.                                 }
  1219.                             }
  1220.                           box_num_2++;
  1221.                           if (box_num_2 >= 4)
  1222.                             box_num_2=0;
  1223.                         }
  1224.                     }
  1225.                   box_num_2=1;
  1226.                   for (box_num_1=0; box_num_1 < 4; ++box_num_1)
  1227.                     {
  1228.                       line_x1=box[box_num_1].x;
  1229.                       line_y1=box[box_num_1].y;
  1230.                       line_x2=box[box_num_2].x;
  1231.                       line_y2=box[box_num_2].y;
  1232.                       box_num_2++;
  1233.                       draw_line(&line_x1,&line_y1,&line_x2,&line_y2,shading);
  1234.                       if (box_num_2 >= 4)
  1235.                         box_num_2=0;
  1236.                     }
  1237.                   if ((prime_ptr->base_z == (char) 1)
  1238.                   &&  (prime_ptr->right->base_z == (char) 1)
  1239.                   &&  (prime_ptr->down->base_z == (char) 0)
  1240.                   &&  (prime_ptr->down->right->base_z == (char) 0))
  1241.                     {
  1242.                       if (prime_ptr->left != NULL)
  1243.                         {
  1244.                           if (prime_ptr->left->base_z == (char) 0)
  1245.                             {
  1246.                               shading=0;
  1247.                               line_x1=box[0].x;
  1248.                               line_y1=box[0].y;
  1249.                               line_x2=box[3].x;
  1250.                               line_y2=box[3].y;
  1251.                               draw_line(&line_x1,&line_y1,&line_x2,&line_y2,
  1252.                                shading);
  1253.                             }
  1254.                         }
  1255.                     }
  1256.                 }
  1257.              }
  1258.            prime_ptr=prime_ptr->lesser_x;
  1259.         }
  1260.     }
  1261.